package com.jwsoft.manager.core.integration.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.module.base.core.helper.DictHelper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.enums.EduSchoolLockAuditDictEnum;
import com.jwsoft.manager.common.enums.EduSchoolLockAuditEnum;
import com.jwsoft.manager.common.enums.SchoolCategoryEnum;
import com.jwsoft.manager.common.vo.eduAddressTree.EduAddressTreeInfoVO;
import com.jwsoft.manager.common.vo.eduAddressTree.EduAddressTreeVO;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.core.dao.model.EduAddressTree;
import com.jwsoft.manager.core.dao.model.EduSchool;
import com.jwsoft.manager.core.dao.service.EduAddressTreeSchoolService;
import com.jwsoft.manager.core.dao.service.EduAddressTreeService;
import com.jwsoft.manager.core.dao.service.EduSchoolService;
import com.jwsoft.manager.core.integration.eduAddressTree.EduAddressTreeIntegration;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import cn.hutool.core.convert.Convert;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.bifang.engine.assistant.core.exception.AppException;
import org.springframework.util.ObjectUtils;
import org.springframework.transaction.annotation.Transactional;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.jwsoft.manager.common.vo.eduSchoolLockAudit.EduSchoolLockAuditVO;
import com.jwsoft.manager.common.vo.eduSchoolLockAudit.EduSchoolLockAuditKeyVO;
import com.jwsoft.manager.common.vo.eduSchoolLockAudit.EduSchoolLockAuditQueryVO;
import com.jwsoft.manager.core.integration.EduSchoolLockAuditIntegration;
import com.jwsoft.manager.core.dao.service.EduSchoolLockAuditService;
import com.jwsoft.manager.core.dao.model.EduSchoolLockAudit;

/**
 * 学校地址锁定确认表业务实现类
 *
 * @author zhang
 * @since 2025-01-08
 */
@ApiService(funcCode = "eduSchoolLockAudit", title = "学校地址锁定确认表")
@Slf4j
public class EduSchoolLockAuditIntegrationImpl implements EduSchoolLockAuditIntegration {

    @Autowired
    public EduSchoolLockAuditService eduSchoolLockAuditService;
    @Autowired
    public EduAddressTreeService eduAddressTreeService;
    @Autowired
    public EduAddressTreeSchoolService eduAddressTreeSchoolService;

    @Autowired
    public EduSchoolService eduSchoolService;
    @Autowired
    public DictHelper dictHelper;
    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    public EduAddressTreeIntegration eduAddressTreeIntegration;

    @Override
    @OpApi(funcCode = "eduSchoolLockAudit0001", title = "学校地址锁定确认表分页查询", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public PageInfo<EduSchoolLockAuditVO> getList(EduSchoolLockAuditQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        QueryWrapper<EduSchoolLockAudit> eduSchoolLockAuditQueryWrapper = new QueryWrapper<>();
        eduSchoolLockAuditQueryWrapper.lambda()
                .eq(!ObjectUtils.isEmpty(vo.getSchoolLockAuditId()), EduSchoolLockAudit::getSchoolLockAuditId, vo.getSchoolLockAuditId())
                .eq(!ObjectUtils.isEmpty(vo.getSchoolId()), EduSchoolLockAudit::getSchoolId, vo.getSchoolId())
                .eq(!ObjectUtils.isEmpty(vo.getSchoolCategory()), EduSchoolLockAudit::getSchoolCategory, vo.getSchoolCategory())
                .eq(!ObjectUtils.isEmpty(vo.getAreaCode()), EduSchoolLockAudit::getAreaCode, vo.getAreaCode())
                .eq(!ObjectUtils.isEmpty(vo.getAuditStatus()), EduSchoolLockAudit::getAuditStatus, vo.getAuditStatus())
                .eq(!ObjectUtils.isEmpty(vo.getLockStatus()), EduSchoolLockAudit::getLockStatus, vo.getLockStatus())
                .eq(!ObjectUtils.isEmpty(vo.getAreaType()), EduSchoolLockAudit::getAreaType, vo.getAreaType())
                .like(!ObjectUtils.isEmpty(vo.getAreaName()), EduSchoolLockAudit::getAreaName, vo.getAreaName())
                .orderByDesc(EduSchoolLockAudit::getSchoolId)
                .orderByDesc(EduSchoolLockAudit::getAddressName);
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduSchoolLockAudit> list = eduSchoolLockAuditService.list(eduSchoolLockAuditQueryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduSchoolLockAudit> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduSchoolLockAuditVO> resultList = Convert.toList(EduSchoolLockAuditVO.class, pageInfo.getList());
        for (EduSchoolLockAuditVO eduSchoolLockAuditVO : resultList) {
            String addressName = eduSchoolLockAuditVO.getAddressName();
            String areaName = eduSchoolLockAuditVO.getAreaName();
            eduSchoolLockAuditVO.setWzaddressName(addressName.replace("/", "") + areaName);
        }
        // 转义数据字典值
        dictHelper.valueToName(resultList, Arrays.asList(EduSchoolLockAuditDictEnum.values()));
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "eduSchoolLockAudit0002", title = "学校地址锁定确认表根据主键查询详情", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public EduSchoolLockAuditVO getById(EduSchoolLockAuditKeyVO vo) {
        EduSchoolLockAudit entity = eduSchoolLockAuditService.getById(vo.getSchoolLockAuditId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduSchoolLockAuditVO result = Convert.convert(EduSchoolLockAuditVO.class, entity);
        return result;
    }

    /**
     * 保存前统一校验
     */
    @Override
    @OpApi(funcCode = "eduSchoolLockAudit0003", title = "学校地址锁定确认表保存前校验", funcType = FuncTypeEnum.other, checkPrivilege = BoolEnum.FALSE)
    public void checkSave(EduSchoolLockAuditVO vo) {
        //主键为空为新增校验

        //主键不为空为修改校验
    }

    @Override
    @OpApi(funcCode = "eduSchoolLockAudit0004", title = "学校地址锁定确认表新增", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "eduSchoolLockAudit0004",
            operationName = "学校地址锁定确认表新增",
            dataType = "schoolLockAuditId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduSchoolLockAuditVO add(EduSchoolLockAuditVO vo) {
        //保存前校验
        checkSave(vo);
        //保存数据
        EduSchoolLockAudit entity = Convert.convert(EduSchoolLockAudit.class, vo);
        eduSchoolLockAuditService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setSchoolLockAuditId(entity.getSchoolLockAuditId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduSchoolLockAudit0005", title = "学校地址锁定确认表修改", funcType = FuncTypeEnum.update)
    @SaveOplog(
            operationType = "eduSchoolLockAudit0005",
            operationName = "学校地址锁定确认表修改",
            dataType = "schoolLockAuditId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduSchoolLockAuditVO edit(EduSchoolLockAuditVO vo) {
        if (ObjectUtils.isEmpty(vo.getSchoolLockAuditId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduSchoolLockAudit oldEntity = eduSchoolLockAuditService.getById(vo.getSchoolLockAuditId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        //保存前校验
        checkSave(vo);
        //保存数据
        EduSchoolLockAudit entity = Convert.convert(EduSchoolLockAudit.class, vo);
        eduSchoolLockAuditService.updateById(entity);
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduSchoolLockAudit0006", title = "学校地址锁定确认表根据主键删除", funcType = FuncTypeEnum.delete)
    @SaveOplog(
            operationType = "eduSchoolLockAudit0006",
            operationName = "学校地址锁定确认表删除",
            dataType = "schoolLockAuditId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void del(EduSchoolLockAuditKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getSchoolLockAuditId())) {
            throw new AppException("传入需要删除的数据主键不能为空!");
        }
        EduSchoolLockAudit entity = eduSchoolLockAuditService.getById(vo.getSchoolLockAuditId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要删除的信息!");
        }
        eduSchoolLockAuditService.removeById(vo.getSchoolLockAuditId());
    }

    @Override
    @OpApi(funcCode = "eduSchoolLockAudit0007", title = "获取推送给学校的数据", funcType = FuncTypeEnum.other, checkPrivilege = BoolEnum.FALSE)
    @Transactional
    public void pushSchoolLockAudit(EduSchoolLockAuditVO vo) {
        RLock lock = redissonClient.getLock("push_school_lock_audit");
        try {
            if (!lock.tryLock(5, 30, TimeUnit.SECONDS)) {
                throw new AppException("正在操作中，请稍后再试");
            }
            // 存储最终结果
            List<EduSchoolLockAuditVO> eduSchoolLockAuditVOS = new ArrayList<>();

            // 查询区级节点
            QueryWrapper<EduAddressTree> eduAddressTreeQueryWrapper = new QueryWrapper<>();
            eduAddressTreeQueryWrapper.lambda()
                    .eq(EduAddressTree::getAreaType, "district");
            List<EduAddressTree> districtNodes = eduAddressTreeService.list(eduAddressTreeQueryWrapper);

            if (CollectionUtils.isEmpty(districtNodes)) {
                throw new AppException("未查询到最上层节点信息");
            }

            // 处理小学的,遍历每个区级节点，递归处理其子节点
            for (EduAddressTree districtNode : districtNodes) {
                processNode(districtNode.getAddressId(), districtNode.getAreaName(), eduSchoolLockAuditVOS, SchoolCategoryEnum.PRIMARY.getType());
            }
            // 处理初中的,遍历每个区级节点，递归处理其子节点
            for (EduAddressTree districtNode : districtNodes) {
                processNode(districtNode.getAddressId(), districtNode.getAreaName(), eduSchoolLockAuditVOS, SchoolCategoryEnum.JUNIOR.getType());
            }

            // 获取 eduSchoolLockAuditVOS 中所有的学校 ID
            List<String> schoolIds = eduSchoolLockAuditVOS.stream()
                    .map(EduSchoolLockAuditVO::getSchoolId)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            if (CollectionUtils.isEmpty(schoolIds)) {
                throw new AppException("未查询到学校信息");
            }

            // 查询学校的行政区划
            QueryWrapper<EduSchool> eduSchoolQueryWrapper = new QueryWrapper<>();
            eduSchoolQueryWrapper.lambda()
                    .in(EduSchool::getOrgId, schoolIds);
            List<EduSchool> schoolList = eduSchoolService.list(eduSchoolQueryWrapper);

            // 构建学校ID与areaCode的Map
            Map<String, String> schoolIdToAreaCodeMap = schoolList.stream()
                    .collect(Collectors.toMap(EduSchool::getOrgId, EduSchool::getAreaCode, (existing, replacement) -> existing));

            // 转换类型
            List<EduSchoolLockAudit> eduSchoolLockAudits = Convert.toList(EduSchoolLockAudit.class, eduSchoolLockAuditVOS);

            // 将 eduSchoolLockAudits 按 address_id 分为新增和更新两组
            List<EduSchoolLockAudit> toUpdate = new ArrayList<>();
            List<EduSchoolLockAudit> toInsert = new ArrayList<>();

            //处理更新还是新增
            for (EduSchoolLockAudit audit : eduSchoolLockAudits) {
                QueryWrapper<EduSchoolLockAudit> eduSchoolLockAuditQueryWrapper = new QueryWrapper<>();
                eduSchoolLockAuditQueryWrapper.lambda()
                        .eq(EduSchoolLockAudit::getAddressId, audit.getAddressId())
                        .eq(EduSchoolLockAudit::getSchoolCategory, audit.getSchoolCategory());
                EduSchoolLockAudit existingAudit = eduSchoolLockAuditService.getOne(eduSchoolLockAuditQueryWrapper);

                if (existingAudit != null) {
                    audit.setSchoolLockAuditId(existingAudit.getSchoolLockAuditId());
                    audit.setAuditStatus(existingAudit.getAuditStatus());
                    audit.setLockStatus(existingAudit.getLockStatus());
                    audit.setLockMassage(existingAudit.getLockMassage());
                    toUpdate.add(audit);
                } else {
                    toInsert.add(audit);
                }
            }

            // 更新时只需要设置学校行政区划
            for (EduSchoolLockAudit eduSchoolLockAudit : toUpdate) {
                eduSchoolLockAudit.setAreaCode(schoolIdToAreaCodeMap.get(eduSchoolLockAudit.getSchoolId()));
            }

            //新增的时候需要把状态都设置为0
            for (EduSchoolLockAudit eduSchoolLockAudit : toInsert) {
                eduSchoolLockAudit.setAreaCode(schoolIdToAreaCodeMap.get(eduSchoolLockAudit.getSchoolId()));
                eduSchoolLockAudit.setAuditStatus("0");
                eduSchoolLockAudit.setLockStatus("0");
            }

            // 批量更新
            if (!toUpdate.isEmpty()) {
                eduSchoolLockAuditService.updateBatchById(toUpdate);
            }

            // 批量新增
            if (!toInsert.isEmpty()) {
                eduSchoolLockAuditService.saveBatch(toInsert);
            }

            // 输出或处理结果
            log.info("推送学校锁定审核数据，共更新节点数: {}", toUpdate.size());
            log.info("推送学校锁定审核数据，共新增节点数: {}", toInsert.size());
        } catch (Exception e) {
            log.error("批量确认失败：{}", e.getMessage(), e);
            throw new AppException(e.getMessage());
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 递归处理节点并拼接完整地址
     *
     * @param parentId    父节点ID
     * @param fullAddress 当前节点的完整地址（逐级拼接）
     * @param resultList  存储结果的集合
     */
    private void processNode(Long parentId, String fullAddress, List<EduSchoolLockAuditVO> resultList, String schoolCategory) {
        // 查询只有一个学校的节点地址
        List<EduSchoolLockAuditVO> singlePrimaryNodes = eduSchoolLockAuditService.getOneSchoolAddressList(parentId, schoolCategory);

        // 设置完整地址到 addressName 字段
        for (EduSchoolLockAuditVO node : singlePrimaryNodes) {
            node.setAddressName(fullAddress);
        }
        resultList.addAll(singlePrimaryNodes);

        // 查询大于一个小学的节点地址
        List<EduSchoolLockAuditVO> multiplePrimaryNodes = eduSchoolLockAuditService.getLtSchoolAddressList(parentId, schoolCategory);

        // 如果大于一个小学的节点不为空，递归处理子节点
        if (!CollectionUtils.isEmpty(multiplePrimaryNodes)) {
            for (EduSchoolLockAuditVO node : multiplePrimaryNodes) {
                // 获取子节点的名称
                String childAddress = node.getAreaName();
                // 拼接完整地址
                String newFullAddress = fullAddress + "/" + childAddress;
                processNode(node.getAddressId(), newFullAddress, resultList, schoolCategory);
            }
        }

    }

    @Override
    @OpApi(funcCode = "eduSchoolLockAudit0008", title = "单个学校地址锁定确认", funcType = FuncTypeEnum.update)
    public EduSchoolLockAuditVO auditSchoolLockAudit(EduSchoolLockAuditVO vo) {
        if (ObjectUtils.isEmpty(vo.getSchoolLockAuditId())) {
            throw new AppException("传入需要确认的主键不能为空!");
        }
        if (ObjectUtils.isEmpty(vo.getAuditStatus())) {
            throw new AppException("传入需要确认的状态不能为空!");
        }

        EduSchoolLockAudit oldEntity = eduSchoolLockAuditService.getById(vo.getSchoolLockAuditId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要确认的信息!");
        }
        // 如果传入的确认状态为通过或不通过
        if (EduSchoolLockAuditEnum.TG.getType().equals(vo.getAuditStatus()) || EduSchoolLockAuditEnum.BTG.getType().equals(vo.getAuditStatus())) {
            // 如果原状态不是未确认或确认失败，则不允许操作
            if (!EduSchoolLockAuditEnum.WQR.getType().equals(oldEntity.getAuditStatus()) && !EduSchoolLockAuditEnum.QRSB.getType().equals(oldEntity.getAuditStatus())) {
                throw new AppException("该条数据已经确认过了，请重新选择");
            }
        }

        if (EduSchoolLockAuditEnum.WQR.getType().equals(vo.getAuditStatus())) {
            if (!EduSchoolLockAuditEnum.WSD.getType().equals(oldEntity.getLockStatus())) {
                throw new AppException("该条数据已经锁定了，请先联系管理员解锁");
            }
        }

        oldEntity.setAuditStatus(vo.getAuditStatus());
        oldEntity.setAuditUser(SessionUtil.getUserId());
        oldEntity.setAuditTime(new Date());
        oldEntity.setAuditMassage(null);
        eduSchoolLockAuditService.updateById(oldEntity);

        return vo;
    }

    @Override
    @OpApi(funcCode = "eduSchoolLockAudit0009", title = "批量学校地址锁定确认", funcType = FuncTypeEnum.update)
    public EduSchoolLockAuditVO batchAuditSchoolLockAudit(EduSchoolLockAuditVO vo) {
        if (CollectionUtils.isEmpty(vo.getIdList())) {
            throw new AppException("传入需要确认的数据不能为空!");
        }
        if (!CollectionUtils.isEmpty(vo.getAuthStatusList())) {
            if (vo.getAuthStatusList().contains(EduSchoolLockAuditEnum.TG.getType()) || vo.getAuthStatusList().contains(EduSchoolLockAuditEnum.BTG.getType())) {
                throw new AppException("存在已通过或未通过的数据，请重新选择!");
            }
        }
        if (ObjectUtils.isEmpty(vo.getAuditStatus())) {
            vo.setAuditStatus(EduSchoolLockAuditEnum.TG.getType());
        }

        RLock lock = redissonClient.getLock("batch_audit_school_lock_audit");
        try {
            if (!lock.tryLock(5, 30, TimeUnit.SECONDS)) {
                throw new AppException("正在确认中，请稍后再试");
            }

            List<String> failedIds = new ArrayList<>();
            Map<String, String> errorMessages = new HashMap<>();
            for (String id : vo.getIdList()) {
                try {
                    EduSchoolLockAuditVO singleVo = new EduSchoolLockAuditVO();
                    singleVo.setSchoolLockAuditId(Long.valueOf(id));
                    singleVo.setAuditStatus(vo.getAuditStatus());
                    auditSchoolLockAudit(singleVo);
                } catch (Exception e) {
                    failedIds.add(id);
                    errorMessages.put(id, e.getMessage());
                }
            }

            // 更新失败记录状态
            if (!failedIds.isEmpty()) {
                List<EduSchoolLockAudit> failedUpdates = failedIds.stream()
                        .map(id -> {
                            EduSchoolLockAudit entity = eduSchoolLockAuditService.getById(id);
                            entity.setAuditStatus(EduSchoolLockAuditEnum.QRSB.getType());
                            entity.setAuditMassage(errorMessages.get(id));
                            entity.setAuditTime(new Date());
                            entity.setAuditUser(SessionUtil.getUserId());
                            return entity;
                        })
                        .collect(Collectors.toList());
                eduSchoolLockAuditService.updateBatchById(failedUpdates);
            }
        } catch (Exception e) {
            log.error("批量确认失败：{}", e.getMessage(), e);
            throw new AppException("操作过程中发生错误", e);
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduSchoolLockAudit0010", title = "单个学校地址锁定", funcType = FuncTypeEnum.update)
    public EduSchoolLockAuditVO auditSchoolLock(EduSchoolLockAuditVO vo) {
        if (ObjectUtils.isEmpty(vo.getSchoolLockAuditId())) {
            throw new AppException("传入需要锁定的主键不能为空!");
        }
        if (ObjectUtils.isEmpty(vo.getLockStatus())) {
            throw new AppException("传入需要锁定的状态不能为空!");
        }
        EduSchoolLockAudit oldEntity = eduSchoolLockAuditService.getById(vo.getSchoolLockAuditId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要锁定或解锁的信息!");
        }

        // 校验锁定或解锁状态
        validateLockStatus(vo, oldEntity);

        // 执行锁定或解锁操作
        try {
            handleLockOperation(vo, oldEntity);
        } catch (Exception e) {
            handleLockFailure(vo, oldEntity, e);
        }

        return vo;
    }

    @Override
    @OpApi(funcCode = "eduSchoolLockAudit0011", title = "批量学校地址锁定", funcType = FuncTypeEnum.update)
    public EduSchoolLockAuditVO batchAuditSchoolLock(EduSchoolLockAuditVO vo) {
        if (CollectionUtils.isEmpty(vo.getIdList())) {
            throw new AppException("传入需要锁定的数据不能为空!");
        }
        if (!CollectionUtils.isEmpty(vo.getLockStatusList())) {
            if (vo.getLockStatusList().contains(EduSchoolLockAuditEnum.YSD.getType())) {
                throw new AppException("存在已锁定的数据，请重新选择!");
            }
        }
        if (ObjectUtils.isEmpty(vo.getLockStatus())) {
            vo.setLockStatus(EduSchoolLockAuditEnum.YSD.getType());
        }
        RLock lock = redissonClient.getLock("batch_audit_school_lock");
        try {
            if (!lock.tryLock(5, 30, TimeUnit.SECONDS)) {
                throw new AppException("正在锁定中，请稍后再试");
            }

            List<String> failedIds = new ArrayList<>();
            Map<String, String> errorMessages = new HashMap<>();
            for (String id : vo.getIdList()) {
                try {
                    EduSchoolLockAuditVO singleVo = new EduSchoolLockAuditVO();
                    singleVo.setSchoolLockAuditId(Long.valueOf(id));
                    singleVo.setLockStatus(vo.getLockStatus());
                    auditSchoolLock(singleVo);
                } catch (Exception e) {
                    failedIds.add(id);
                    errorMessages.put(id, e.getMessage());
                }
            }
            // 更新失败记录状态
            if (!failedIds.isEmpty()) {
                List<EduSchoolLockAudit> failedUpdates = failedIds.stream()
                        .map(id -> {
                            EduSchoolLockAudit entity = eduSchoolLockAuditService.getById(id);
                            entity.setLockStatus(EduSchoolLockAuditEnum.LYSB.getType());
                            entity.setLockMassage(errorMessages.get(id));
                            entity.setLockTime(new Date());
                            entity.setLockUser(SessionUtil.getUserId());
                            return entity;
                        })
                        .collect(Collectors.toList());
                eduSchoolLockAuditService.updateBatchById(failedUpdates);
            }

        } catch (Exception e) {
            log.error("批量锁定失败：{}", e.getMessage(), e);
            throw new AppException("操作过程中发生错误", e);
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }

        return vo;
    }


    // 锁定状态校验
    private void validateLockStatus(EduSchoolLockAuditVO vo, EduSchoolLockAudit oldEntity) {
        String lockStatus = vo.getLockStatus();
        String auditStatus = oldEntity.getAuditStatus();
        String oldLockStatus = oldEntity.getLockStatus();

        // 锁定状态校验
        if (EduSchoolLockAuditEnum.YSD.getType().equals(lockStatus)) {
            if (!EduSchoolLockAuditEnum.WSD.getType().equals(oldLockStatus) && !EduSchoolLockAuditEnum.LYSB.getType().equals(oldLockStatus)) {
                throw new AppException("该条数据已经锁定过了，请重新选择");
            }
        }

        // 解锁状态校验
        if (EduSchoolLockAuditEnum.WSD.getType().equals(lockStatus) && EduSchoolLockAuditEnum.WSD.getType().equals(oldLockStatus)) {
            throw new AppException("该条数据已经解锁过了，请重新选择");
        }

        if (lockStatus.equals(EduSchoolLockAuditEnum.YSD.getType())) {
            if (!EduSchoolLockAuditEnum.TG.getType().equals(auditStatus)) {
                throw new AppException("该条数据不是确认状态，不能锁定");
            }
        }
    }

    // 锁定或解锁操作
    private void handleLockOperation(EduSchoolLockAuditVO vo, EduSchoolLockAudit oldEntity) {
        EduAddressTree entity = eduAddressTreeService.getById(oldEntity.getAddressId());
        EduAddressTreeVO eduAddressTreeVO = Convert.convert(EduAddressTreeVO.class, entity);

        //如果是锁定状态，设置学校信息
        if (EduSchoolLockAuditEnum.YSD.getType().equals(vo.getLockStatus())) {
            updateCheckList(oldEntity, eduAddressTreeVO);
            eduAddressTreeVO.setAffirmFlag(Integer.valueOf(vo.getLockStatus()));
        }

        //如果是解锁状态，设置学校信息
        if (EduSchoolLockAuditEnum.WSD.getType().equals(vo.getLockStatus())) {
            updateCheckListWsd(oldEntity, eduAddressTreeVO);
        }

        EduAddressTreeInfoVO eduAddressTreeInfoVO = new EduAddressTreeInfoVO();
        eduAddressTreeInfoVO.setData(eduAddressTreeVO);

        //更新树节点
        eduAddressTreeIntegration.saveAddressTreeInfo(eduAddressTreeInfoVO);

        oldEntity.setLockStatus(vo.getLockStatus());
        oldEntity.setLockUser(SessionUtil.getUserId());
        oldEntity.setLockTime(new Date());
        oldEntity.setLockMassage(null);
        eduSchoolLockAuditService.updateById(oldEntity);
    }


    // 更新学校列表
    private void updateCheckList(EduSchoolLockAudit oldEntity, EduAddressTreeVO eduAddressTreeVO) {
        String schoolCategory = oldEntity.getSchoolCategory();
        String schoolId = oldEntity.getSchoolId();

        //这个节点上面已经锁定的学校，可能为null
        String primarySchool = eduAddressTreeVO.getPrimarySchool();
        String middleSchool = eduAddressTreeVO.getMiddleSchool();

        //如果这条数据是小学，就看有没有锁过初中，锁过，就把初中弄进去
        if (SchoolCategoryEnum.PRIMARY.getType().equals(schoolCategory)) {
            eduAddressTreeVO.setCheckPrimaryList(Collections.singletonList(schoolId));
            if (!StringUtils.isEmpty(middleSchool)) {
                eduAddressTreeVO.setCheckMiddleList(Arrays.asList(middleSchool));
            }
        } else if (SchoolCategoryEnum.JUNIOR.getType().equals(schoolCategory)) {
            eduAddressTreeVO.setCheckMiddleList(Collections.singletonList(schoolId));
            if (!StringUtils.isEmpty(primarySchool)) {
                eduAddressTreeVO.setCheckPrimaryList(Arrays.asList(primarySchool));
            }
        }
    }

    private void updateCheckListWsd(EduSchoolLockAudit oldEntity, EduAddressTreeVO eduAddressTreeVO) {
        String schoolCategory = oldEntity.getSchoolCategory();
        String schoolId = oldEntity.getSchoolId();

        //这个节点上面已经锁定的学校，可能为null
        String primarySchool = eduAddressTreeVO.getPrimarySchool();
        String middleSchool = eduAddressTreeVO.getMiddleSchool();

        if (SchoolCategoryEnum.PRIMARY.getType().equals(schoolCategory)) {
            eduAddressTreeVO.setCheckPrimaryList(new ArrayList<>());
            if (!StringUtils.isEmpty(middleSchool)) {
                eduAddressTreeVO.setCheckMiddleList(Arrays.asList(middleSchool));
                eduAddressTreeVO.setAffirmFlag(Integer.valueOf(EduSchoolLockAuditEnum.YSD.getType()));
            } else {
                eduAddressTreeVO.setAffirmFlag(Integer.valueOf(EduSchoolLockAuditEnum.WSD.getType()));
            }
        } else if (SchoolCategoryEnum.JUNIOR.getType().equals(schoolCategory)) {
            eduAddressTreeVO.setCheckMiddleList(new ArrayList<>());
            if (!StringUtils.isEmpty(primarySchool)) {
                eduAddressTreeVO.setCheckPrimaryList(Arrays.asList(primarySchool));
                eduAddressTreeVO.setAffirmFlag(Integer.valueOf(EduSchoolLockAuditEnum.YSD.getType()));
            } else {
                eduAddressTreeVO.setAffirmFlag(Integer.valueOf(EduSchoolLockAuditEnum.WSD.getType()));
            }
        }
    }

    // 处理锁定或解锁失败
    private void handleLockFailure(EduSchoolLockAuditVO vo, EduSchoolLockAudit oldEntity, Exception e) {
        //只有锁定失败的时候才设置状态为锁定失败，如果是解锁失败，状态还是锁定状态
        if (EduSchoolLockAuditEnum.WSD.getType().equals(vo.getLockStatus())) {
            oldEntity.setLockStatus(EduSchoolLockAuditEnum.YSD.getType());
        } else {
            oldEntity.setLockStatus(EduSchoolLockAuditEnum.LYSB.getType());
        }

        oldEntity.setLockUser(SessionUtil.getUserId());
        oldEntity.setLockTime(new Date());
        oldEntity.setLockMassage(e.getMessage());
        eduSchoolLockAuditService.updateById(oldEntity);
    }

}
